from pylons.controllers import WSGIController
from pylons.templating import render_mako as render
import harstorage.lib.helpers as h
from harstorage.lib.MongoHandler import MongoDB
from pylons import config
from pprint import pprint
from bson.objectid import ObjectId

import time

class BaseController(WSGIController):

    """
    The base Controller API

    Provides the BaseController class for subclassing.
    """

    def __call__(self, environ, start_response):
        """Invoke the Controller"""

        # WSGIController.__call__ dispatches to the Controller method
        # the request is routed to. This routing information is
        # available in environ['pylons.routes_dict']
        try:
            return WSGIController.__call__(self, environ, start_response)
        finally:
            None

    def _get_screenshot_url(self, screenshot_id):
        if screenshot_id:
            return "/results/screenshot?id=" + str(screenshot_id)
        else:
            return None

    def get_multi_har_info(self, results):
        """ Returns the list of the screenshot urls and _ids corresponding to the given search result.
        If the searchresult is a list, the last document is used. If the document is not a multi-har-document
        "None" is returned """

        if not results:
            return None

        mdb_handler = MongoDB()

        if type(results) is list:
            doc = results[-1]
        else:
            doc = results



        if not doc.get("multi_har"):
            master_doc = doc.get("master_doc")
            if not master_doc:
                return None
            else:
                doc = mdb_handler.collection.find_one({"_id": ObjectId(master_doc)})

        out = []

        sub_docs = mdb_handler.mh_collection.find({"master_doc": doc["_id"]}, fields = ["screenshot", "transaction_time", "info", "url", "error_msg"])

        idx = 0
        for sub_doc in sub_docs:
            out.append({"screenshot_url": self._get_screenshot_url(sub_doc.get("screenshot")) or "/results/screenshot?id=dummy",
                        "transaction_time": sub_doc.get("transaction_time", 0),
                        "info": sub_doc.get("info"),
                        "error": sub_doc.get("error_msg"),
                        "url": sub_doc["url"],
                        "idx": idx})
            idx += 1

        return out


    def get_timeline_results(self, series, from_ts, to_ts, zoom_min, zoom_max, navi, multi_har_idx, metrics):

        if navi is None and from_ts is None and to_ts is None and zoom_min is None and zoom_max is None:
            navi = "1h"


        # set/adjust time-range
        if zoom_min and zoom_max:
            from_ts = h.to_unix_date(zoom_min)
            to_ts = h.to_unix_date(zoom_max)

        if navi == "all":
            from_ts = None
            to_ts = None
        elif navi == "1w":
            from_ts = time.time() - h.SECONDS_ONE_WEEK
            to_ts = None
        elif navi == "1d":
            from_ts = time.time() - h.SECONDS_ONE_DAY
            to_ts = None
        elif navi == "1h":
            from_ts = time.time() - h.SECONDS_ONE_HOUR
            to_ts = None
        elif navi == "15min":
            from_ts = time.time() - h.SECONDS_15_MINUTES
            to_ts = None

        # Set of metrics to exclude (due to missing data)
        exclude = set()
        data = []
        for index in range(len(metrics)):
            data.append([])

        # prepare the time-range filter
        the_filter = {"series": ObjectId(series), "timestamp": {}}
        if to_ts:
            the_filter["timestamp"]["$lte"] = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(to_ts))
        if from_ts:
            the_filter["timestamp"]["$gte"] = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(from_ts))

        if not the_filter["timestamp"]:
            del the_filter["timestamp"]

        # add "sub_docs" if multi_har_idx is set
        if multi_har_idx:
            the_collection = MongoDB().mh_collection
            the_filter["idx"] = int(multi_har_idx)
            metrics.append("master_doc")
        else:
            the_collection = MongoDB().collection

        # Read data for timeline from database in custom format (hash separated)
        results = the_collection.find(the_filter,
                                      fields = metrics)

        results = list(results.sort("timestamp")) # sort and load

        multi_har_info = self.get_multi_har_info(results)

        return results, multi_har_info

